package mazeBueno1;

import java.util.ArrayList;
import java.util.Random;



public class Maze {
	private int logColisiones = 0;
	private int width;
	private int height;
	private boolean[][] map;
	private Random rnd;

	public Maze(int width, int height) {
		this.width = width;
		this.height = height;
		//System.out.println((width*2-1) + " " + (height*2-1));
		
	}
	
	
	public void generateMultipleChoice(long seed, int whiteNoise) {
		generate(seed);
		Random b = new Random();
		for (int i = 0; i < this.width*2-1; i++) {
			for (int j = 0; j < this.height*2-1;j++) {
				if ((i+j)%2 != 0)
					if (b.nextInt(whiteNoise) == 0)
						this.map[i][j] = true;
			}
		}
	}
	public void generate(long seed) {
		System.out.println("Generando nuevo laberinto (" + this.width + "," + this.height + ")con semilla: " + seed);
		long time = System.currentTimeMillis();
		logColisiones = 0;
		
		this.map = new boolean[width*2-1][height*2-1];
		rnd = new Random(seed);
		int xStart = 0;
		int yStart = 0;
		//this.map[width/2][height/2] = true;
		//generate(width/2,height/2);
		this.map[xStart*2][yStart*2] = true;
		generate(xStart*2,yStart*2);
		System.out.println("Colisiones: " + logColisiones);
		System.out.println("Tiempo: " + (System.currentTimeMillis() - time) + "ms");
	}
	
	private void generate(int x, int y) {
		
		ArrayList<Point> points = new ArrayList<Point>();
		Point cPoint;
		int xPos = x;
		int yPos = y;
		
		int dir = rnd.nextInt(4);
		points.add(new Point(x,y, dir));
		
		while(true) {
			cPoint = points.get(points.size()-1);
			xPos = cPoint.getX();
			yPos = cPoint.getY();
			dir = cPoint.getDir();
			
			if (!this.nextPlace(xPos,yPos,dir)) {
				this.setPath(xPos,yPos,dir);
				points.add(new Point(nextX(xPos,dir),nextY(yPos,dir),rnd.nextInt(4)));
			}
			else {
				if (cPoint.nextDir() == cPoint.getStartDir())
					points.remove(points.size()-1);
				if (points.size()== 0)
					break; //end while
			}
			

		}
		
		
		/*int startDir = rnd.nextInt(4);
		
		int colision = 0;
		
		for (int i = startDir; i < startDir+4; i++) {
			int dir = i%4;
			if (!this.nextPlace(x, y, dir)) {
				colision++;
				//System.out.println("Breaking bond at: (" + x + "," + y + ") in direction: " + dir);
				this.setPath(x,y,dir);
				generate(nextX(x,dir),nextY(y,dir));
			}			
		}
		
		if (colision == 0) 
			logColisiones++;*/
	}
	
	private void setPath(int x, int y, int dir) {
		switch(dir) {
		case 0: {
			this.map[x][y-1] = true;
			this.map[x][y-2] = true;
			break;
		}
		case 1:{
			this.map[x+1][y] = true;
			this.map[x+2][y] = true;
			break;
		}
		case 2:{
			this.map[x][y+1] = true;
			this.map[x][y+2] = true;
			break;
		}
		case 3:{
			this.map[x-1][y] = true;
			this.map[x-2][y] = true;
			break;
		}
		}
	}
	private int nextY(int y, int dir) {
		if (dir == 0)
			return y-2;
		if (dir == 2)
			return y+2;
		return y;
	}
	private int nextX(int x, int dir) {
		if (dir == 1)
			return x+2;
		if (dir == 3)
			return x-2;
		return x;
	}
	private boolean nextPlace(int x, int y, int dir) {
		switch(dir) {
		case 0: {
			if (y == 0)
				return true;
			return this.map[x][y-2];
		}
		case 1: {
			if (x >= this.width*2-2)
				return true;
			return this.map[x+2][y];
		}
		case 2: {
			if (y >= this.height*2-2)
				return true;
			return this.map[x][y+2];
		}
		case 3: {
			if (x == 0)
				return true;
			return this.map[x-2][y];
		}
		}
		return true;
	}
	public boolean getSquare(int x, int y) {
		return this.map[x][y];
	}
	
}
